/*
  c-pthread-queue - c implementation of a bounded buffer queue using posix threads
  Copyright (C) 2008  Matthew Dickinson

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <pthread.h>
#include "queue.h"

void queue_enqueue(queue_t *queue, void *value)
{
  pthread_mutex_lock(&(queue->mutex));
  while (queue->size == queue->capacity)
	pthread_cond_wait(&(queue->cond_full), &(queue->mutex));
  queue->buffer[queue->in] = value;
  ++ queue->size;
  ++ queue->in;
  queue->in %= queue->capacity;
  pthread_mutex_unlock(&(queue->mutex));
  pthread_cond_broadcast(&(queue->cond_empty));
}

void *queue_dequeue(queue_t *queue)
{
  pthread_mutex_lock(&(queue->mutex));
  while (queue->size == 0)
	pthread_cond_wait(&(queue->cond_empty), &(queue->mutex));
  void *value;
  value = queue->buffer[queue->out];
  -- queue->size;
  ++ queue->out;
  queue->out %= queue->capacity;
  pthread_mutex_unlock(&(queue->mutex));
  pthread_cond_broadcast(&(queue->cond_full));
  return value;
}

int queue_size(queue_t *queue)
{
  pthread_mutex_lock(&(queue->mutex));
  int size = queue->size;
  pthread_mutex_unlock(&(queue->mutex));
  return size;
}
